# Do not run data set on git/github until privacy has been cleared
################
##### Data  
################
################
##### Research
################
################
##### Guess work   
################
################
#####  Notes:
################
### Source ---->  Input ----> Model ----> Policy Estimates (output)
###  (_so)        (_in)       (_mo)        (_pe)
### values      functions   functions      values
###             & values    & values
### arguments in functions should used "_var" and functions should "_f"
#invisible( list2env(call_params_f(),.GlobalEnv) )


# Each analytic code chunk will begin by listing all the inputs it needs, and
# the outputs it produces.
# - inputs: list
# - outputs: list
#### The key essential analytic steps are wrapted in a function   
#chunk_name_of_chunk <- function(){
##########################################
##########################################  
#
# here goes the essential analytic content
#
##########################################
##########################################  
#    return( )                         # A list with all the objects
#}                                     # generated inside the function
# The following line executes the code chunk and deposits its results
# into the current R enviornment:
#invisible( list2env(chunk_name_of_chunk(),.GlobalEnv) )
#
##### Execute values of the functions above when needed for the text:
# Anything under this comment is to create objects that are used in the body of
# text. Not to be used in the final results (could be deleted). Each of these
# object should end with the suffix _temp
# - inputs: none
# - outputs: all sources coming from data, research and guesswork
chunk_sources <- function(){
###############################################################################
###############################################################################

    #############
    ##### Setup
    #############  
    nsims_so <- 1e4
    policy_estimate_so <- "Main Equation"
    rescale_so <- TRUE
    #############
    ##### Data  
    #############

  # Create objects for data extracted from various sources

    r_input1_so <- 0.1
    r_input2_so <- 0.2
    #############
    ##### Research
    #############

  # Create objects for parameters extracted from research papers
    q_input1_so <- 0.5
    q_input2_so <- 0.8
    #############
    ##### Guess work   
    #############

  # Create objects for variables from educated guesses or estimates  

    #############
    ##### Notes:
    #############

  # Notes for the objects defined above, including sources, explanations, etc.
    k_input1_so <- 3
    k_input2_so <- 4

    #return( sapply( ls(pattern= "_so\\b"), function(x) get(x)) )
    return (
      list("nsims_so" = nsims_so,
           "policy_estimate_so" = policy_estimate_so,
           "rescale_so" = rescale_so,
           "r_input1_so" = r_input1_so,
           "r_input2_so" = r_input2_so,
           "q_input1_so" = q_input1_so,
           "q_input2_so" = q_input2_so,
           "k_input1_so" = k_input1_so,
           "k_input2_so" = k_input2_so
           )
    )
}
invisible(list2env(chunk_sources(),.GlobalEnv) )

1 Introduction

Summary of the issue and introduction to the policy analysis is conducted.

The goal of this analysis is to provide the best empirical information for policy makers debating the implementation of “mass deworming interventions” policy. This document describes all the analytical steps required to reproduce the analysis, and displaying the actual computer code use in each step. In addition to this report, the reader can find all the materials to reproduce the findings presented here in GitHub. The main output, presented in the results section of this report, can also be explored interactively for different assumptions on the corresponding shiny app.

1.1 Source Information for data + analytical methods

For this dynamic document, we are conducting this specific analysis, and it is computed using three different approaches:

  1. Approach 1

In this first approach, the effect on earnings over the entire lifecycle is predicted by extrapolating the effects on hours worked by individuals in the original treatment group, ten years after the intervention.

  1. Approach 2

In this second approach, benefits follow the same principle as in approach 1 (increase in lifetime earnings), but it uses updated data on the effects on the labor market outcomes. Instead of projecting a trend of earnings into the future (after the estimated impact of the 10 year follow-up), this analysis uses additional data from 15 and 20 year follow-ups after the original intervention.

  1. Approach 3

In this third and final approach, the report borrowed some methodological elements from Baird et al. (2016) and Hamory et al. (2020) and sought feedback from a key policy partner to best identify one clear output to inform policy makers. BITSS worked in collaboration with the NGO Evidence Action, a key technical assistance partner in this area. Evidence Action provided insights on what are the most relevant costs and benefits from the perspectives of policy makers, and on certain aspects of the analysis that could be updated with present-day data.

???

1.2 Key policy estimates for policy makers

#my thoughts: should we forefront the conclusions before the methodology?

#Sandra: I think we should specify which approach we use to generate the graph, but keep the methodology before the conclusions.

???

2 Methodology

Explain what the final estimate indicator is, how the analysis is to be performed, what factors are looked at, etc.

The final estimate is the net present value of the deworming treatment, referred to as the Net Present Value (NPV). The report first describes the common elements across all three approaches, and then describe each approach in detail.

2.1 Common Structure

Introduce the starting point and the final policy estimate. Include alternative indicators of our final policy estimates as well.

The starting point is a comparison of a stream of benefits and costs over the lifetime of the recipients of deworming. The final policy estimate is the discounted sum of all costs and benefits, known as the Net Present Value (NPV). Benefits are equal to the additional lifetime earnings that individuals are expected to generate due to deworming treatment. These additional earnings are computed as a discounted sum over their working lifetime.

At a high level all three approaches focus on the same type of benefits: the increase in incomes over the lifetime of beneficiaries of deworming. This is likely an under-estimate of the benefits as it does not quantify the non-pecuniary effects of improved health. The costs can be separated into direct costs of implementing and evaluating deworming programs, and indirect costs, such as additional costs to the education system as a result of increased child attendance, associated with the benefits of deworming.

The main differences in benefits across the three approaches have to do with how to predict the earnings profiles over a lifecycle, and how to account for differences in worm prevalence rates and length of treatment across settings. Approaches 1 and 2 use different earning profiles, and approach 3 combines both earning profiles and adjusts for possible differences in prevalence rates of worm infections and length of treatment.

The main differences in costs between scenarios have to do with a) whether indirect costs are included, and b) how to compute the relevant unit cost for the analysis. The first two approaches include indirect costs and use the unit costs of a specific country (Kenya) where the study was originally conducted, while the third approach does not include indirect costs and use unit costs of various countries from data provided by Evidence Action.

2.1.1 Main Equation (the model)

Explanation for the main equation

Show all the details \[\begin{equation} y = r + q - k \label{eq:1} \tag{1} \end{equation}\]

Where:

  • \(y\): one-liner to define y
  • \(r\): one-liner to define r
  • \(k\): one-liner to define k

2.1.2 Alternative Equation

Explanation for the alternative equation

Show all the details \[\begin{equation} y = r + q + k \label{eq:2} \tag{2} \end{equation}\]

Where:

  • \(y\): one-liner to define y
  • \(r\): one-liner to define r
  • \(k\): one-liner to define k
# - inputs:
# - outputs:
chunk_test <- function(){
###############################################################################
###############################################################################  

    # random equation to use as our main equation to get the final result
    mainequation_f <- function(r_final_var = 1,
                               q_final_var = 1,
                               k_final_var = 1) {
        return (r_final_var + q_final_var - k_final_var)
    }

    # random equation to use as our alternative equation to get the final result
    alternative_f <- function( r_final_var = 1,
                               q_final_var = 1,
                               k_final_var = 1){
      return (r_final_var + q_final_var + k_final_var)

    }

###############################################################################
###############################################################################  
    return(list("mainequation_f" = mainequation_f, "alternative_f" = alternative_f))    # Try to return only functions
}
invisible( list2env(chunk_test(),.GlobalEnv) )

##### Execute values of the functions above when needed for the text:
mainequation_in <- mainequation_f()
alternative_in <- alternative_f()

2.2 Sub Common Components:

2.2.1 Component 1 (“\(r\)”)

This is the formula used to calculate component 11

Show all the details \[\begin{equation} r = X \times \lambda_1 + (1 - X) \times \lambda_2 \label{eq:3} \tag{3} \end{equation}\]

Where:

  • \(r\): one-liner for r
  • \(X\): one-liner for X
  • \(\lambda_1\): one-liner for \(\lambda_1\)
  • \(\lambda_2\): one-liner for \(\lambda_2\)
# - inputs: factors of r
# - outputs: r value
chunk_r <- function(){
###############################################################################
###############################################################################  

    r_function_f <- function(r_input1_var = r_input1_so , r_input2_var = r_input2_so) {  
        r_input1_var - r_input2_var

    }

###############################################################################
###############################################################################  
    return(list("r_function_f" = r_function_f))
}

invisible( list2env(chunk_r(),.GlobalEnv) )

2.3 Approach 1: Baird et al.

2.3.1 Component 2 (“\(q\)”)

This is the formula used to calculate component 22

Show all the details \[\begin{equation} q = \text{input} \times \alpha_0 (1 + g)^{X}(1 + \hat{\beta_1} X + \hat{\beta_2} X^2) \label{eq:} \tag{4} \end{equation}\]

Where:

  • \(q\): one-liner to define q
  • \(\alpha_0\): one-liner to define \(\alpha_0\)
  • \(g\): one-liner to define g
  • \(\hat{\beta_1}\): one-liner to define \(\hat{\beta_1}\)
  • \(\hat{\beta_2}\): one-liner to define \(\hat{\beta_2}\)
# - inputs: factors of q
# - outputs: q value
chunk_q <- function(){
###############################################################################
###############################################################################  

    q_function_f <- function(q_input1_var = q_input1_so , q_input2_var = q_input2_so) {  
        (q_input1_var * q_input2_var)^2

    }

###############################################################################
###############################################################################  
    return(list("q_function_f" = q_function_f))
}

invisible( list2env(chunk_q(),.GlobalEnv) )

2.4 Approach 2: Hamory et al.

2.4.1 Component 3 (“\(k\)”)

This is the formula used to calculate component 33

Show all the details \[\begin{equation} k = R \times X + (1 - R) \times X \label{eq:5} \tag{5} \end{equation}\]

Where:

  • \(k\): one-liner to define k
  • \(R\): one-liner to define R
# - inputs: factors of q
# - outputs: q value
chunk_k <- function(){
###############################################################################
###############################################################################  

    k_function_f <- function(k_input1_var = k_input1_so , k_input2_var = k_input2_so) {  
        (k_input1_var * k_input2_var)^2

    }

###############################################################################
###############################################################################  
    return(list("k_function_f" = k_function_f))
}

invisible( list2env(chunk_k(),.GlobalEnv) )

2.5 Summary of All Approaches

Approach Part 1 Part 2
1.1 Specification of Approach 1 with Part 1 Assumption 1 Specification of Approach 1 with Part 2 Assumption 1
1.2 Specification of Approach 1 with Part 1 Assumption 2 Specification of Aprroach 1 with Part 2 Assumption 2
2.1 Specification of Approach 2 with Part 1 Assumption 1 Specification of Approach 2 with Part 2 Assumption 1
2.2 Specification of Approach 2 with Part 1 Assumption 2 Specification of Approach 2 with Part 2 Assumption 2

Bolded row is the assumptions and the approach we use to generate the main policy estimate plot.

3 Main results

Show all the details

#unit test function
unit_test_f <- function(to_test_var, original_var, main_run_var = TRUE){
    if (main_run_var == TRUE) {
        if (length(to_test_var) > 1) {
            fails_test <- ( abs(sd(to_test_var) - original_var) > 0.0001 )
            text_val <- sd(to_test_var)
        } else {
            fails_test <- ( abs(to_test_var - original_var) > 0.0001 )
            text_val <- to_test_var
        }
        if (fails_test) {
            print(paste("Output has change at",
                        deparse(substitute(to_test_var) ),
                        " to ", text_val) )
        }
      }
}

one_run <-
  function(r_input1_var1 = r_input1_so,
           r_input2_var1 = r_input2_so,
           q_input1_var1 = q_input1_so,
           q_input2_var1 = q_input2_so,
           k_input1_var1 = k_input1_so,
           k_input2_var1 = k_input2_so){# Variables needed to generate the final policy estimates

    r_in <- r_function_f(r_input1_var = r_input1_var1,
                         r_input2_var = r_input2_var1)
    q_in <- q_function_f(q_input1_var = q_input1_var1,
                         q_input2_var = q_input2_var1)
    k_in <- k_function_f(k_input1_var = k_input1_var1,
                         k_input2_var = k_input2_var1)
    return (list("r_in" = r_in,
                 "q_in" = q_in,
                 "k_in" = k_in))
           }

invisible(list2env(one_run(), .GlobalEnv))
# - perform the calculations to achieve final results

result1 <- mainequation_f(r_final_var = r_in,
                          q_final_var = q_in,
                          k_final_var = k_in)
result2 <- alternative_f(r_final_var = r_in,
                          q_final_var = q_in,
                          k_final_var = k_in)
#...

results_table <- data.frame("results1" =   c("results", NA,
                                             NA) ,
                        "results2" =  c(NA, "results", NA),
                        "results3" = c("results", NA,
                                             "results"),

                        row.names = c("situation1", "situation2", "situation3"))

kable(results_table, caption = "Table Caption") %>%
  kable_styling("striped", full_width = F)
Table 3.1: Table Caption
results1 results2 results3
situation1 results NA results
situation2 NA results NA
situation3 NA NA results

4 Monte Carlo Simulations

sim_data1_f <- function(nsims = 1e2,
                      r_input1_var2,
                      r_input1_var2_sd,
                      r_input2_var2,
                      r_input2_var2_sd,
                      q_input1_var2,
                      q_input1_var2_sd,
                      q_input2_var2,
                      q_input2_var2_sd,
                      k_input1_var2,
                      k_input1_var2_sd,
                      k_input2_var2,
                      k_input2_var2_sd){
    ################
    ###### Draws   
    ################  
  start_time <- Sys.time()
  set.seed(142857)
  r1_sim <- rnorm(n = nsims, mean = r_input1_var2, sd= r_input1_var2_sd)
  r2_sim <- rnorm(n = nsims, mean = r_input2_var2, sd= r_input2_var2_sd)
  q1_sim <- rnorm(n = nsims, mean = q_input1_var2, sd= q_input1_var2_sd)
  q2_sim <- rnorm(n = nsims, mean = q_input2_var2, sd= q_input2_var2_sd)
  k1_sim <- rnorm(n = nsims, mean = k_input1_var2, sd= k_input1_var2_sd)
  k2_sim <- rnorm(n = nsims, mean = k_input2_var2, sd= k_input2_var2_sd)

    ################
    ###### Runs    
    ################

  result1_sim <- rep(NA, nsims) #result1
  result2_sim <- rep(NA, nsims) #result2

  for (i in 1:nsims){
    invisible(list2env(
      one_run(r_input1_var1 = r1_sim[i],
              r_input2_var1 = r2_sim[i],
              q_input1_var1 = q1_sim[i],
              q_input2_var1 = q2_sim[i],
              k_input1_var1 = k1_sim[i],
              k_input2_var1 = k2_sim[i]
              ), .GlobalEnv))

    result1_sim[i] <- mainequation_f(r_final_var = r_in,
                          q_final_var = q_in,
                          k_final_var = k_in)
    result2_sim[i] <- alternative_f(r_final_var = r_in,
                          q_final_var = q_in,
                          k_final_var = k_in)
  }
    total_time <- Sys.time() - start_time
    return(list("result1_sim" = result1_sim,
                "result2_sim" = result2_sim))


}

policy_estimates_varnames <- c(
  "result1_sim",
  "result2_sim"
)

policy_estimates_text <- c(
  "Main Equation",
  "Alternative Equation"
)
# Run Monte Carlo simulation for our main model
result1_sim_all <- sim_data1_f(nsims = nsims_so,
                      r_input1_var2 = r_input1_so,
                      r_input1_var2_sd = r_input1_so * 0.1,
                      r_input2_var2 = r_input2_so,
                      r_input2_var2_sd = r_input2_so * 0.1,
                      q_input1_var2 = q_input1_so,
                      q_input1_var2_sd = q_input1_so * 0.1,
                      q_input2_var2 = q_input2_so,
                      q_input2_var2_sd = q_input2_so * 0.1,
                      k_input1_var2 = k_input1_so,
                      k_input1_var2_sd = k_input1_so * 0.1,
                      k_input2_var2 = k_input2_so,
                      k_input2_var2_sd = k_input2_so * 0.1

                             )



################
###### Results/Viz
################


library(plotly)


plot1 <- generate_plot_f(result1_sim_all, policy_estimate_so, rescale_so)[[1]] +
      labs(y = NULL,
       x = "Main Estimate" ,
       title = "Project Title",
       subtitle = "Distribution of Key Indicator"
       )
print(plot1)

5 References


  1. Notes of referenced section↩︎

  2. Notes on referenced section↩︎

  3. Notes on referenced section↩︎

LS0tCnRpdGxlOiAiPGNlbnRlcj48ZGl2IGNsYXNzPSAnbXl0aXRsZSc+VGVtcGxhdGU8L2Rpdj48L2NlbnRlcj4iCmRhdGU6ICI8Y2VudGVyPjxkaXYgY2xhc3M9J215c3VidGl0bGUnPmByIGZvcm1hdChTeXMudGltZSgpLCAnJWQgJUIsICVZJylgPC9kaXY+PC9jZW50ZXI+IgphdXRob3I6ICI8Y2VudGVyPjxkaXYgY2xhc3MgPSAnY29udHJpYnV0b3JzJz5Db250cmlidXRvcnM8L2Rpdj48L2NlbnRlcj4iCm91dHB1dDoKICBib29rZG93bjo6aHRtbF9kb2N1bWVudDI6CiAgICBjb2RlX2Rvd25sb2FkOiB5ZXMKICAgIGNvZGVfZm9sZGluZzogaGlkZQogICAgY3NzOiBzdHlsZS5jc3MKICAgIGhpZ2hsaWdodDogdGFuZ28KICAgIGluY2x1ZGVzOgogICAgICBhZnRlcl9ib2R5OiBmb290ZXIuaHRtbAogICAga2VlcF9tZDogeWVzCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcwogICAgc21vb3RoX3Njcm9sbDogbm8KICAgIHRoZW1lOiBjZXJ1bGVhbgogICAgdG9jOiB5ZXMKICAgIHRvY19jb2xsYXBzZWQ6IG5vCiAgICB0b2NfZGVwdGg6IDMKICAgIHRvY19mbG9hdDogeWVzCiAgaHRtbF9kb2N1bWVudDoKICAgIGRmX3ByaW50OiBwYWdlZAogICAgdG9jOiB5ZXMKICAgIHRvY19kZXB0aDogJzMnCiAgd29yZF9kb2N1bWVudDogbnVsbApsaW5rLWNpdGF0aW9uczogeWVzCnBkZl9kb2N1bWVudDoKICBleHRyYV9kZXBlbmRlbmNpZXM6IHhjb2xvcgogIGZpZ19jYXB0aW9uOiBubwpiaWJsaW9ncmFwaHk6IGJpYmxpb2dyYXBoeS5iaWIKCmtuaXQ6CiAgIyByZW5kZXIgdG8gaW5kZXguaHRtbCBmb3IgR2l0SHViIHBhZ2VzCiAgIyByZW5kZXIgdG8gMDVfZmluYWxfb3BhLmh0bWwgdG8ga25pdCBsb2NhbGx5CiAgIyBZQU1MIGRvZXMgbm90IHN1cHBvcnQgY29tbWVudGluZyBpbnNpZGUgdGhlIGZ1bmN0aW9uCiAgKGZ1bmN0aW9uKGlucHV0X2ZpbGUsIGVuY29kaW5nKSB7CiAgcm1hcmtkb3duOjpyZW5kZXIoaW5wdXRfZmlsZSwgZW5jb2Rpbmc9ZW5jb2RpbmcsIG91dHB1dF9maWxlPWZpbGUucGF0aCgiLi4iLCAnaW5kZXguaHRtbCcpKTsKICBybWFya2Rvd246OnJlbmRlcihpbnB1dF9maWxlLCBlbmNvZGluZz1lbmNvZGluZywgb3V0cHV0X2ZpbGU9JzAwX3RlbXBsYXRlLmh0bWwnKTsKICB9KQotLS0KXGRlZlxibHVle1xjb2xvcntibHVlfX0KXGRlZlxyZWR7XGNvbG9ye3JlZH19CgoKYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0UsIHB1cmwgPSBGQUxTRX0KIyBMb2FkaW5nIHJlcXVpcmVkIGxpYnJhcmllcwpsaXN0Lm9mLnBhY2thZ2VzIDwtIGMoInRpZHl2ZXJzZSIsICJoZXJlIiwgImthYmxlRXh0cmEiLCAicmVhZHhsIiwicGxvdGx5IiwKICAgICAgICAgICAgICAgICAgICAgICAgImJvb2tkb3duIiwgInJvb3RTb2x2ZSIsInNoaW55QlMiLCAic2hpbnl0aGVtZXMiLAogICAgICAgICAgICAgICAgICAgICAgICAiZ2dwbG90MiIpCgpuZXcucGFja2FnZXMgPC0gbGlzdC5vZi5wYWNrYWdlc1shKGxpc3Qub2YucGFja2FnZXMgJWluJSBpbnN0YWxsZWQucGFja2FnZXMoKVssIlBhY2thZ2UiXSldCmlmKGxlbmd0aChuZXcucGFja2FnZXMpKSBpbnN0YWxsLnBhY2thZ2VzKG5ldy5wYWNrYWdlcywgcmVwb3M9ICJodHRwOi8vY3Jhbi5jbnIuYmVya2VsZXkuZWR1LyIpCgpsYXBwbHkobGlzdC5vZi5wYWNrYWdlcywgbGlicmFyeSwgY2hhcmFjdGVyLm9ubHkgPSBUUlVFKQoKa25pdHI6Om9wdHNfa25pdCRzZXQocm9vdC5kaXIgPSBoZXJlKCkpCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSkKCnNldHdkKGhlcmUoKSkKCiMgUHVybCB0byBhbGxfYW5hbHlzaXMuUgpvcHRpb25zKGtuaXRyLmR1cGxpY2F0ZS5sYWJlbCA9ICJhbGxvdyIpICMgd29ya2Fyb3VuZCBmb3IgcHVybCBlcnJvcgprbml0cjo6cHVybCgiY29kZS8wMF90ZW1wbGF0ZS5SbWQiLCAiY29kZS9zaGlueV9hcHAvYWxsX2FuYWx5c2lzLlIiKQoKcHJpbnRfY29kZSA8LSBUUlVFCmBgYAoKCmBgYHtyIHBhcmFtZXRlcnMsIGVjaG89cHJpbnRfY29kZX0KIyBEbyBub3QgcnVuIGRhdGEgc2V0IG9uIGdpdC9naXRodWIgdW50aWwgcHJpdmFjeSBoYXMgYmVlbiBjbGVhcmVkCiMjIyMjIyMjIyMjIyMjIyMKIyMjIyMgRGF0YSAgCiMjIyMjIyMjIyMjIyMjIyMKIyMjIyMjIyMjIyMjIyMjIwojIyMjIyBSZXNlYXJjaAojIyMjIyMjIyMjIyMjIyMjCiMjIyMjIyMjIyMjIyMjIyMKIyMjIyMgR3Vlc3Mgd29yayAgIAojIyMjIyMjIyMjIyMjIyMjCiMjIyMjIyMjIyMjIyMjIyMKIyMjIyMgIE5vdGVzOgojIyMjIyMjIyMjIyMjIyMjCiMjIyBTb3VyY2UgLS0tLT4gIElucHV0IC0tLS0+IE1vZGVsIC0tLS0+IFBvbGljeSBFc3RpbWF0ZXMgKG91dHB1dCkKIyMjICAoX3NvKSAgICAgICAgKF9pbikgICAgICAgKF9tbykgICAgICAgIChfcGUpCiMjIyB2YWx1ZXMgICAgICBmdW5jdGlvbnMgICBmdW5jdGlvbnMgICAgICB2YWx1ZXMKIyMjICAgICAgICAgICAgICYgdmFsdWVzICAgICYgdmFsdWVzCiMjIyBhcmd1bWVudHMgaW4gZnVuY3Rpb25zIHNob3VsZCB1c2VkICJfdmFyIiBhbmQgZnVuY3Rpb25zIHNob3VsZCAiX2YiCiNpbnZpc2libGUoIGxpc3QyZW52KGNhbGxfcGFyYW1zX2YoKSwuR2xvYmFsRW52KSApCgoKIyBFYWNoIGFuYWx5dGljIGNvZGUgY2h1bmsgd2lsbCBiZWdpbiBieSBsaXN0aW5nIGFsbCB0aGUgaW5wdXRzIGl0IG5lZWRzLCBhbmQKIyB0aGUgb3V0cHV0cyBpdCBwcm9kdWNlcy4KIyAtIGlucHV0czogbGlzdAojIC0gb3V0cHV0czogbGlzdAojIyMjIFRoZSBrZXkgZXNzZW50aWFsIGFuYWx5dGljIHN0ZXBzIGFyZSB3cmFwdGVkIGluIGEgZnVuY3Rpb24gICAKI2NodW5rX25hbWVfb2ZfY2h1bmsgPC0gZnVuY3Rpb24oKXsKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyAgCiMKIyBoZXJlIGdvZXMgdGhlIGVzc2VudGlhbCBhbmFseXRpYyBjb250ZW50CiMKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyAgCiMgICAgcmV0dXJuKCApICAgICAgICAgICAgICAgICAgICAgICAgICMgQSBsaXN0IHdpdGggYWxsIHRoZSBvYmplY3RzCiN9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgZ2VuZXJhdGVkIGluc2lkZSB0aGUgZnVuY3Rpb24KIyBUaGUgZm9sbG93aW5nIGxpbmUgZXhlY3V0ZXMgdGhlIGNvZGUgY2h1bmsgYW5kIGRlcG9zaXRzIGl0cyByZXN1bHRzCiMgaW50byB0aGUgY3VycmVudCBSIGVudmlvcm5tZW50OgojaW52aXNpYmxlKCBsaXN0MmVudihjaHVua19uYW1lX29mX2NodW5rKCksLkdsb2JhbEVudikgKQojCiMjIyMjIEV4ZWN1dGUgdmFsdWVzIG9mIHRoZSBmdW5jdGlvbnMgYWJvdmUgd2hlbiBuZWVkZWQgZm9yIHRoZSB0ZXh0OgojIEFueXRoaW5nIHVuZGVyIHRoaXMgY29tbWVudCBpcyB0byBjcmVhdGUgb2JqZWN0cyB0aGF0IGFyZSB1c2VkIGluIHRoZSBib2R5IG9mCiMgdGV4dC4gTm90IHRvIGJlIHVzZWQgaW4gdGhlIGZpbmFsIHJlc3VsdHMgKGNvdWxkIGJlIGRlbGV0ZWQpLiBFYWNoIG9mIHRoZXNlCiMgb2JqZWN0IHNob3VsZCBlbmQgd2l0aCB0aGUgc3VmZml4IF90ZW1wCgpgYGAKCgpgYGB7ciBzb3VyY2VzLCBldmFsID0gVFJVRSwgZWNobz1wcmludF9jb2RlLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIC0gaW5wdXRzOiBub25lCiMgLSBvdXRwdXRzOiBhbGwgc291cmNlcyBjb21pbmcgZnJvbSBkYXRhLCByZXNlYXJjaCBhbmQgZ3Vlc3N3b3JrCmNodW5rX3NvdXJjZXMgPC0gZnVuY3Rpb24oKXsKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCgogICAgIyMjIyMjIyMjIyMjIwogICAgIyMjIyMgU2V0dXAKICAgICMjIyMjIyMjIyMjIyMgIAogICAgbnNpbXNfc28gPC0gMWU0CiAgICBwb2xpY3lfZXN0aW1hdGVfc28gPC0gIk1haW4gRXF1YXRpb24iCiAgICByZXNjYWxlX3NvIDwtIFRSVUUKICAgICMjIyMjIyMjIyMjIyMKICAgICMjIyMjIERhdGEgIAogICAgIyMjIyMjIyMjIyMjIwoKICAjIENyZWF0ZSBvYmplY3RzIGZvciBkYXRhIGV4dHJhY3RlZCBmcm9tIHZhcmlvdXMgc291cmNlcwoKICAgIHJfaW5wdXQxX3NvIDwtIDAuMQogICAgcl9pbnB1dDJfc28gPC0gMC4yCiAgICAjIyMjIyMjIyMjIyMjCiAgICAjIyMjIyBSZXNlYXJjaAogICAgIyMjIyMjIyMjIyMjIwoKICAjIENyZWF0ZSBvYmplY3RzIGZvciBwYXJhbWV0ZXJzIGV4dHJhY3RlZCBmcm9tIHJlc2VhcmNoIHBhcGVycwogICAgcV9pbnB1dDFfc28gPC0gMC41CiAgICBxX2lucHV0Ml9zbyA8LSAwLjgKICAgICMjIyMjIyMjIyMjIyMKICAgICMjIyMjIEd1ZXNzIHdvcmsgICAKICAgICMjIyMjIyMjIyMjIyMKCiAgIyBDcmVhdGUgb2JqZWN0cyBmb3IgdmFyaWFibGVzIGZyb20gZWR1Y2F0ZWQgZ3Vlc3NlcyBvciBlc3RpbWF0ZXMgIAoKCiAgICAjIyMjIyMjIyMjIyMjCiAgICAjIyMjIyBOb3RlczoKICAgICMjIyMjIyMjIyMjIyMKCiAgIyBOb3RlcyBmb3IgdGhlIG9iamVjdHMgZGVmaW5lZCBhYm92ZSwgaW5jbHVkaW5nIHNvdXJjZXMsIGV4cGxhbmF0aW9ucywgZXRjLgogICAga19pbnB1dDFfc28gPC0gMwogICAga19pbnB1dDJfc28gPC0gNAoKICAgICNyZXR1cm4oIHNhcHBseSggbHMocGF0dGVybj0gIl9zb1xcYiIpLCBmdW5jdGlvbih4KSBnZXQoeCkpICkKICAgIHJldHVybiAoCiAgICAgIGxpc3QoIm5zaW1zX3NvIiA9IG5zaW1zX3NvLAogICAgICAgICAgICJwb2xpY3lfZXN0aW1hdGVfc28iID0gcG9saWN5X2VzdGltYXRlX3NvLAogICAgICAgICAgICJyZXNjYWxlX3NvIiA9IHJlc2NhbGVfc28sCiAgICAgICAgICAgInJfaW5wdXQxX3NvIiA9IHJfaW5wdXQxX3NvLAogICAgICAgICAgICJyX2lucHV0Ml9zbyIgPSByX2lucHV0Ml9zbywKICAgICAgICAgICAicV9pbnB1dDFfc28iID0gcV9pbnB1dDFfc28sCiAgICAgICAgICAgInFfaW5wdXQyX3NvIiA9IHFfaW5wdXQyX3NvLAogICAgICAgICAgICJrX2lucHV0MV9zbyIgPSBrX2lucHV0MV9zbywKICAgICAgICAgICAia19pbnB1dDJfc28iID0ga19pbnB1dDJfc28KICAgICAgICAgICApCiAgICApCn0KaW52aXNpYmxlKGxpc3QyZW52KGNodW5rX3NvdXJjZXMoKSwuR2xvYmFsRW52KSApCmBgYAoKIyBJbnRyb2R1Y3Rpb24KU3VtbWFyeSBvZiB0aGUgaXNzdWUgYW5kIGludHJvZHVjdGlvbiB0byB0aGUgcG9saWN5IGFuYWx5c2lzIGlzIGNvbmR1Y3RlZC4KClRoZSBnb2FsIG9mIHRoaXMgYW5hbHlzaXMgaXMgdG8gcHJvdmlkZSB0aGUgYmVzdCBlbXBpcmljYWwgaW5mb3JtYXRpb24gZm9yIHBvbGljeSBtYWtlcnMgZGViYXRpbmcgdGhlIGltcGxlbWVudGF0aW9uIG9mICJtYXNzIGRld29ybWluZyBpbnRlcnZlbnRpb25zIiBwb2xpY3kuIFRoaXMgZG9jdW1lbnQgZGVzY3JpYmVzIGFsbCB0aGUgYW5hbHl0aWNhbCBzdGVwcyByZXF1aXJlZCB0byByZXByb2R1Y2UgdGhlIGFuYWx5c2lzLCBhbmQgZGlzcGxheWluZyB0aGUgYWN0dWFsIGNvbXB1dGVyIGNvZGUgdXNlIGluIGVhY2ggc3RlcC4gSW4gYWRkaXRpb24gdG8gdGhpcyByZXBvcnQsIHRoZSByZWFkZXIgY2FuIGZpbmQgYWxsIHRoZSBtYXRlcmlhbHMgdG8gcmVwcm9kdWNlIHRoZSBmaW5kaW5ncyBwcmVzZW50ZWQgaGVyZSBpbiBHaXRIdWIuIFRoZSBtYWluIG91dHB1dCwgcHJlc2VudGVkIGluIHRoZSByZXN1bHRzIHNlY3Rpb24gb2YgdGhpcyByZXBvcnQsIGNhbiBhbHNvIGJlIGV4cGxvcmVkIGludGVyYWN0aXZlbHkgZm9yIGRpZmZlcmVudCBhc3N1bXB0aW9ucyBvbiB0aGUgY29ycmVzcG9uZGluZyBzaGlueSBhcHAuCgojIyBTb3VyY2UgSW5mb3JtYXRpb24gZm9yIGRhdGEgKyBhbmFseXRpY2FsIG1ldGhvZHMKCkZvciB0aGlzIGR5bmFtaWMgZG9jdW1lbnQsIHdlIGFyZSBjb25kdWN0aW5nIHRoaXMgc3BlY2lmaWMgYW5hbHlzaXMsIGFuZCBpdCBpcyBjb21wdXRlZCB1c2luZyB0aHJlZSBkaWZmZXJlbnQgYXBwcm9hY2hlczoKCjEuIFtBcHByb2FjaCAxXShodHRwczovL2JpdHNzLW9wYS5naXRodWIuaW8vb3BhLWRld29ybWluZy8jcmVmLWJhaXJkMjAxNndvcm1zKQoKSW4gdGhpcyBmaXJzdCBhcHByb2FjaCwgdGhlIGVmZmVjdCBvbiBlYXJuaW5ncyBvdmVyIHRoZSBlbnRpcmUgbGlmZWN5Y2xlIGlzIHByZWRpY3RlZCBieSBleHRyYXBvbGF0aW5nIHRoZSBlZmZlY3RzIG9uIGhvdXJzIHdvcmtlZCBieSBpbmRpdmlkdWFscyBpbiB0aGUgb3JpZ2luYWwgdHJlYXRtZW50IGdyb3VwLCB0ZW4geWVhcnMgYWZ0ZXIgdGhlIGludGVydmVudGlvbi4KCjIuIFtBcHByb2FjaCAyXShodHRwczovL2JpdHNzLW9wYS5naXRodWIuaW8vb3BhLWRld29ybWluZy8jcmVmLWtscHM0KQoKSW4gdGhpcyBzZWNvbmQgYXBwcm9hY2gsIGJlbmVmaXRzIGZvbGxvdyB0aGUgc2FtZSBwcmluY2lwbGUgYXMgaW4gYXBwcm9hY2ggMSAoaW5jcmVhc2UgaW4gbGlmZXRpbWUgZWFybmluZ3MpLCBidXQgaXQgdXNlcyB1cGRhdGVkIGRhdGEgb24gdGhlIGVmZmVjdHMgb24gdGhlIGxhYm9yIG1hcmtldCBvdXRjb21lcy4gSW5zdGVhZCBvZiBwcm9qZWN0aW5nIGEgdHJlbmQgb2YgZWFybmluZ3MgaW50byB0aGUgZnV0dXJlIChhZnRlciB0aGUgZXN0aW1hdGVkIGltcGFjdCBvZiB0aGUgMTAgeWVhciBmb2xsb3ctdXApLCB0aGlzIGFuYWx5c2lzIHVzZXMgYWRkaXRpb25hbCBkYXRhIGZyb20gMTUgYW5kIDIwIHllYXIgZm9sbG93LXVwcyBhZnRlciB0aGUgb3JpZ2luYWwgaW50ZXJ2ZW50aW9uLgoKMy4gW0FwcHJvYWNoIDNdKGh0dHBzOi8vYml0c3Mtb3BhLmdpdGh1Yi5pby9vcGEtZGV3b3JtaW5nLyMyM19BcHByb2FjaF8zOl9Db21iaW5hdGlvbl9vZl9QcmV2aW91c19BcHByb2FjaGVzX2FuZF9JbnB1dF9Gcm9tX0tleV9Qb2xpY3lfUGFydG5lcnMpCgpJbiB0aGlzIHRoaXJkIGFuZCBmaW5hbCBhcHByb2FjaCwgdGhlIHJlcG9ydCBib3Jyb3dlZCBzb21lIG1ldGhvZG9sb2dpY2FsIGVsZW1lbnRzIGZyb20gQmFpcmQgZXQgYWwuIChbMjAxNl0oaHR0cHM6Ly9iaXRzcy1vcGEuZ2l0aHViLmlvL29wYS1kZXdvcm1pbmcvI3JlZi1iYWlyZDIwMTZ3b3JtcykpIGFuZCBIYW1vcnkgZXQgYWwuIChbMjAyMF0oaHR0cHM6Ly9iaXRzcy1vcGEuZ2l0aHViLmlvL29wYS1kZXdvcm1pbmcvI3JlZi1rbHBzNCkpIGFuZCBzb3VnaHQgZmVlZGJhY2sgZnJvbSBhIGtleSBwb2xpY3kgcGFydG5lciB0byBiZXN0IGlkZW50aWZ5IG9uZSBjbGVhciBvdXRwdXQgdG8gaW5mb3JtIHBvbGljeSBtYWtlcnMuIEJJVFNTIHdvcmtlZCBpbiBjb2xsYWJvcmF0aW9uIHdpdGggdGhlIE5HTyBFdmlkZW5jZSBBY3Rpb24sIGEga2V5IHRlY2huaWNhbCBhc3Npc3RhbmNlIHBhcnRuZXIgaW4gdGhpcyBhcmVhLiBFdmlkZW5jZSBBY3Rpb24gcHJvdmlkZWQgaW5zaWdodHMgb24gd2hhdCBhcmUgdGhlIG1vc3QgcmVsZXZhbnQgY29zdHMgYW5kIGJlbmVmaXRzIGZyb20gdGhlIHBlcnNwZWN0aXZlcyBvZiBwb2xpY3kgbWFrZXJzLCBhbmQgb24gY2VydGFpbiBhc3BlY3RzIG9mIHRoZSBhbmFseXNpcyB0aGF0IGNvdWxkIGJlIHVwZGF0ZWQgd2l0aCBwcmVzZW50LWRheSBkYXRhLgoKCgo/Pz8gIAoKIyMgS2V5IHBvbGljeSBlc3RpbWF0ZXMgZm9yIHBvbGljeSBtYWtlcnMgIApgYGB7cn0KI215IHRob3VnaHRzOiBzaG91bGQgd2UgZm9yZWZyb250IHRoZSBjb25jbHVzaW9ucyBiZWZvcmUgdGhlIG1ldGhvZG9sb2d5PwoKI1NhbmRyYTogSSB0aGluayB3ZSBzaG91bGQgc3BlY2lmeSB3aGljaCBhcHByb2FjaCB3ZSB1c2UgdG8gZ2VuZXJhdGUgdGhlIGdyYXBoLCBidXQga2VlcCB0aGUgbWV0aG9kb2xvZ3kgYmVmb3JlIHRoZSBjb25jbHVzaW9ucy4KYGBgCgpgYGB7ciBmaW5hbC1vdXRwdXR9CmBgYAo/Pz8KCiMgTWV0aG9kb2xvZ3kKCkV4cGxhaW4gd2hhdCB0aGUgZmluYWwgZXN0aW1hdGUgaW5kaWNhdG9yIGlzLCBob3cgdGhlIGFuYWx5c2lzIGlzIHRvIGJlIHBlcmZvcm1lZCwgd2hhdCBmYWN0b3JzIGFyZSBsb29rZWQgYXQsIGV0Yy4KClRoZSBmaW5hbCBlc3RpbWF0ZSBpcyB0aGUgbmV0IHByZXNlbnQgdmFsdWUgb2YgdGhlIGRld29ybWluZyB0cmVhdG1lbnQsIHJlZmVycmVkIHRvIGFzIHRoZSBOZXQgUHJlc2VudCBWYWx1ZSAoTlBWKS4gVGhlIHJlcG9ydCBmaXJzdCBkZXNjcmliZXMgdGhlIGNvbW1vbiBlbGVtZW50cyBhY3Jvc3MgYWxsIHRocmVlIGFwcHJvYWNoZXMsIGFuZCB0aGVuIGRlc2NyaWJlIGVhY2ggYXBwcm9hY2ggaW4gZGV0YWlsLgoKIyMgQ29tbW9uIFN0cnVjdHVyZQoKSW50cm9kdWNlIHRoZSBzdGFydGluZyBwb2ludCBhbmQgdGhlIGZpbmFsIHBvbGljeSBlc3RpbWF0ZS4gSW5jbHVkZSBhbHRlcm5hdGl2ZSBpbmRpY2F0b3JzIG9mIG91ciBmaW5hbCBwb2xpY3kgZXN0aW1hdGVzIGFzIHdlbGwuICAKClRoZSBzdGFydGluZyBwb2ludCBpcyBhIGNvbXBhcmlzb24gb2YgYSBzdHJlYW0gb2YgYmVuZWZpdHMgYW5kIGNvc3RzIG92ZXIgdGhlIGxpZmV0aW1lIG9mIHRoZSByZWNpcGllbnRzIG9mIGRld29ybWluZy4gVGhlIGZpbmFsIHBvbGljeSBlc3RpbWF0ZSBpcyB0aGUgZGlzY291bnRlZCBzdW0gb2YgYWxsIGNvc3RzIGFuZCBiZW5lZml0cywga25vd24gYXMgdGhlIE5ldCBQcmVzZW50IFZhbHVlIChOUFYpLiBCZW5lZml0cyBhcmUgZXF1YWwgdG8gdGhlIGFkZGl0aW9uYWwgbGlmZXRpbWUgZWFybmluZ3MgdGhhdCBpbmRpdmlkdWFscyBhcmUgZXhwZWN0ZWQgdG8gZ2VuZXJhdGUgZHVlIHRvIGRld29ybWluZyB0cmVhdG1lbnQuIFRoZXNlIGFkZGl0aW9uYWwgZWFybmluZ3MgYXJlIGNvbXB1dGVkIGFzIGEgZGlzY291bnRlZCBzdW0gb3ZlciB0aGVpciB3b3JraW5nIGxpZmV0aW1lLgoKQXQgYSBoaWdoIGxldmVsIGFsbCB0aHJlZSBhcHByb2FjaGVzIGZvY3VzIG9uIHRoZSBzYW1lIHR5cGUgb2YgYmVuZWZpdHM6IHRoZSBpbmNyZWFzZSBpbiBpbmNvbWVzIG92ZXIgdGhlIGxpZmV0aW1lIG9mIGJlbmVmaWNpYXJpZXMgb2YgZGV3b3JtaW5nLiBUaGlzIGlzIGxpa2VseSBhbiB1bmRlci1lc3RpbWF0ZSBvZiB0aGUgYmVuZWZpdHMgYXMgaXQgZG9lcyBub3QgcXVhbnRpZnkgdGhlIG5vbi1wZWN1bmlhcnkgZWZmZWN0cyBvZiBpbXByb3ZlZCBoZWFsdGguIFRoZSBjb3N0cyBjYW4gYmUgc2VwYXJhdGVkIGludG8gZGlyZWN0IGNvc3RzIG9mIGltcGxlbWVudGluZyBhbmQgZXZhbHVhdGluZyBkZXdvcm1pbmcgcHJvZ3JhbXMsIGFuZCBpbmRpcmVjdCBjb3N0cywgc3VjaCBhcyBhZGRpdGlvbmFsIGNvc3RzIHRvIHRoZSBlZHVjYXRpb24gc3lzdGVtIGFzIGEgcmVzdWx0IG9mIGluY3JlYXNlZCBjaGlsZCBhdHRlbmRhbmNlLCBhc3NvY2lhdGVkIHdpdGggdGhlIGJlbmVmaXRzIG9mIGRld29ybWluZy4KClRoZSBtYWluIGRpZmZlcmVuY2VzIGluIGJlbmVmaXRzIGFjcm9zcyB0aGUgdGhyZWUgYXBwcm9hY2hlcyBoYXZlIHRvIGRvIHdpdGggaG93IHRvIHByZWRpY3QgdGhlIGVhcm5pbmdzIHByb2ZpbGVzIG92ZXIgYSBsaWZlY3ljbGUsIGFuZCBob3cgdG8gYWNjb3VudCBmb3IgZGlmZmVyZW5jZXMgaW4gd29ybSBwcmV2YWxlbmNlIHJhdGVzIGFuZCBsZW5ndGggb2YgdHJlYXRtZW50IGFjcm9zcyBzZXR0aW5ncy4gQXBwcm9hY2hlcyAxIGFuZCAyIHVzZSBkaWZmZXJlbnQgZWFybmluZyBwcm9maWxlcywgYW5kIGFwcHJvYWNoIDMgY29tYmluZXMgYm90aCBlYXJuaW5nIHByb2ZpbGVzIGFuZCBhZGp1c3RzIGZvciBwb3NzaWJsZSBkaWZmZXJlbmNlcyBpbiBwcmV2YWxlbmNlIHJhdGVzIG9mIHdvcm0gaW5mZWN0aW9ucyBhbmQgbGVuZ3RoIG9mIHRyZWF0bWVudC4KClRoZSBtYWluIGRpZmZlcmVuY2VzIGluIGNvc3RzIGJldHdlZW4gc2NlbmFyaW9zIGhhdmUgdG8gZG8gd2l0aCBhKSB3aGV0aGVyIGluZGlyZWN0IGNvc3RzIGFyZSBpbmNsdWRlZCwgYW5kIGIpIGhvdyB0byBjb21wdXRlIHRoZSByZWxldmFudCB1bml0IGNvc3QgZm9yIHRoZSBhbmFseXNpcy4gVGhlIGZpcnN0IHR3byBhcHByb2FjaGVzIGluY2x1ZGUgaW5kaXJlY3QgY29zdHMgYW5kIHVzZSB0aGUgdW5pdCBjb3N0cyBvZiBhIHNwZWNpZmljIGNvdW50cnkgKEtlbnlhKSB3aGVyZSB0aGUgc3R1ZHkgd2FzIG9yaWdpbmFsbHkgY29uZHVjdGVkLCB3aGlsZSB0aGUgdGhpcmQgYXBwcm9hY2ggZG9lcyBub3QgaW5jbHVkZSBpbmRpcmVjdCBjb3N0cyBhbmQgdXNlIHVuaXQgY29zdHMgb2YgdmFyaW91cyBjb3VudHJpZXMgZnJvbSBkYXRhIHByb3ZpZGVkIGJ5IEV2aWRlbmNlIEFjdGlvbi4KCiMjIyBNYWluIEVxdWF0aW9uICh0aGUgbW9kZWwpCgpFeHBsYW5hdGlvbiBmb3IgdGhlIG1haW4gZXF1YXRpb24KCjxkZXRhaWxzPjxzdW1tYXJ5PlNob3cgYWxsIHRoZSBkZXRhaWxzPC9zdW1tYXJ5PgpcYmVnaW57ZXF1YXRpb259CnkgPSByICsgcSAtIGsKXGxhYmVse2VxOjF9Clx0YWd7MX0KXGVuZHtlcXVhdGlvbn0KCldoZXJlOgoKLSAkeSQ6IG9uZS1saW5lciB0byBkZWZpbmUgeQotICRyJDogb25lLWxpbmVyIHRvIGRlZmluZSByCi0gJGskOiBvbmUtbGluZXIgdG8gZGVmaW5lIGsKCjwvZGV0YWlscz4KCgoKIyMjIEFsdGVybmF0aXZlIEVxdWF0aW9uCgpFeHBsYW5hdGlvbiBmb3IgdGhlIGFsdGVybmF0aXZlIGVxdWF0aW9uCgo8ZGV0YWlscz48c3VtbWFyeT5TaG93IGFsbCB0aGUgZGV0YWlsczwvc3VtbWFyeT4KXGJlZ2lue2VxdWF0aW9ufQp5ID0gciArIHEgKyBrClxsYWJlbHtlcToyfQpcdGFnezJ9ClxlbmR7ZXF1YXRpb259CgpXaGVyZToKCi0gJHkkOiBvbmUtbGluZXIgdG8gZGVmaW5lIHkKLSAkciQ6IG9uZS1saW5lciB0byBkZWZpbmUgcgotICRrJDogb25lLWxpbmVyIHRvIGRlZmluZSBrCgpgYGB7ciB0ZXN0LCBldmFsPVRSVUV9CiMgLSBpbnB1dHM6CiMgLSBvdXRwdXRzOgpjaHVua190ZXN0IDwtIGZ1bmN0aW9uKCl7CiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyAgCgogICAgIyByYW5kb20gZXF1YXRpb24gdG8gdXNlIGFzIG91ciBtYWluIGVxdWF0aW9uIHRvIGdldCB0aGUgZmluYWwgcmVzdWx0CiAgICBtYWluZXF1YXRpb25fZiA8LSBmdW5jdGlvbihyX2ZpbmFsX3ZhciA9IDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBxX2ZpbmFsX3ZhciA9IDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrX2ZpbmFsX3ZhciA9IDEpIHsKICAgICAgICByZXR1cm4gKHJfZmluYWxfdmFyICsgcV9maW5hbF92YXIgLSBrX2ZpbmFsX3ZhcikKICAgIH0KCiAgICAjIHJhbmRvbSBlcXVhdGlvbiB0byB1c2UgYXMgb3VyIGFsdGVybmF0aXZlIGVxdWF0aW9uIHRvIGdldCB0aGUgZmluYWwgcmVzdWx0CiAgICBhbHRlcm5hdGl2ZV9mIDwtIGZ1bmN0aW9uKCByX2ZpbmFsX3ZhciA9IDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBxX2ZpbmFsX3ZhciA9IDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrX2ZpbmFsX3ZhciA9IDEpewogICAgICByZXR1cm4gKHJfZmluYWxfdmFyICsgcV9maW5hbF92YXIgKyBrX2ZpbmFsX3ZhcikKCiAgICB9CgojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMgIAogICAgcmV0dXJuKGxpc3QoIm1haW5lcXVhdGlvbl9mIiA9IG1haW5lcXVhdGlvbl9mLCAiYWx0ZXJuYXRpdmVfZiIgPSBhbHRlcm5hdGl2ZV9mKSkgICAgIyBUcnkgdG8gcmV0dXJuIG9ubHkgZnVuY3Rpb25zCn0KaW52aXNpYmxlKCBsaXN0MmVudihjaHVua190ZXN0KCksLkdsb2JhbEVudikgKQoKIyMjIyMgRXhlY3V0ZSB2YWx1ZXMgb2YgdGhlIGZ1bmN0aW9ucyBhYm92ZSB3aGVuIG5lZWRlZCBmb3IgdGhlIHRleHQ6Cm1haW5lcXVhdGlvbl9pbiA8LSBtYWluZXF1YXRpb25fZigpCmFsdGVybmF0aXZlX2luIDwtIGFsdGVybmF0aXZlX2YoKQpgYGAKCgo8L2RldGFpbHM+CgojIyBTdWIgQ29tbW9uIENvbXBvbmVudHM6CgojIyMgQ29tcG9uZW50IDEgKCIkciQiKQoKVGhpcyBpcyB0aGUgZm9ybXVsYSB1c2VkIHRvIGNhbGN1bGF0ZSBjb21wb25lbnQgMVteMV0KCjxkZXRhaWxzPjxzdW1tYXJ5PlNob3cgYWxsIHRoZSBkZXRhaWxzPC9zdW1tYXJ5PgpcYmVnaW57ZXF1YXRpb259CnIgPSBYIFx0aW1lcyBcbGFtYmRhXzEgICsgKDEgLSBYKSBcdGltZXMgXGxhbWJkYV8yClxsYWJlbHtlcTozfQpcdGFnezN9ClxlbmR7ZXF1YXRpb259CgpXaGVyZToKCi0gJHIkOiBvbmUtbGluZXIgZm9yIHIKLSAkWCQ6IG9uZS1saW5lciBmb3IgWAotICRcbGFtYmRhXzEkOiBvbmUtbGluZXIgZm9yICRcbGFtYmRhXzEkCi0gJFxsYW1iZGFfMiQ6IG9uZS1saW5lciBmb3IgJFxsYW1iZGFfMiQKCmBgYHtyIGNvbXAxLCAgZWNobz1wcmludF9jb2RlLCBldmFsPVRSVUV9CiMgLSBpbnB1dHM6IGZhY3RvcnMgb2YgcgojIC0gb3V0cHV0czogciB2YWx1ZQpjaHVua19yIDwtIGZ1bmN0aW9uKCl7CiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyAgCgogICAgcl9mdW5jdGlvbl9mIDwtIGZ1bmN0aW9uKHJfaW5wdXQxX3ZhciA9IHJfaW5wdXQxX3NvICwgcl9pbnB1dDJfdmFyID0gcl9pbnB1dDJfc28pIHsgIAogICAgICAgIHJfaW5wdXQxX3ZhciAtIHJfaW5wdXQyX3ZhcgoKICAgIH0KCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyAgCiAgICByZXR1cm4obGlzdCgicl9mdW5jdGlvbl9mIiA9IHJfZnVuY3Rpb25fZikpCn0KCmludmlzaWJsZSggbGlzdDJlbnYoY2h1bmtfcigpLC5HbG9iYWxFbnYpICkKCmBgYAo8L2RldGFpbHM+CgojIyBBcHByb2FjaCAxOiBbQmFpcmQgZXQgYWwuXShodHRwczovL2JpdHNzLW9wYS5naXRodWIuaW8vb3BhLWRld29ybWluZy8jcmVmLWJhaXJkMjAxNndvcm1zKQojIyMgQ29tcG9uZW50IDIgKCIkcSQiKQoKVGhpcyBpcyB0aGUgZm9ybXVsYSB1c2VkIHRvIGNhbGN1bGF0ZSBjb21wb25lbnQgMlteMl0KCjxkZXRhaWxzPjxzdW1tYXJ5PlNob3cgYWxsIHRoZSBkZXRhaWxzPC9zdW1tYXJ5PgpcYmVnaW57ZXF1YXRpb259CnEgPSAgXHRleHR7aW5wdXR9IFx0aW1lcyBcYWxwaGFfMCAoMSArIGcpXntYfSgxICsgXGhhdHtcYmV0YV8xfSBYICsgXGhhdHtcYmV0YV8yfSBYXjIpClxsYWJlbHtlcTp9Clx0YWd7NH0KXGVuZHtlcXVhdGlvbn0KCldoZXJlOgoKLSAkcSQ6IG9uZS1saW5lciB0byBkZWZpbmUgcQotICRcYWxwaGFfMCQ6IG9uZS1saW5lciB0byBkZWZpbmUgJFxhbHBoYV8wJAotICRnJDogb25lLWxpbmVyIHRvIGRlZmluZSBnCi0gJFxoYXR7XGJldGFfMX0kOiBvbmUtbGluZXIgdG8gZGVmaW5lICRcaGF0e1xiZXRhXzF9JAotICRcaGF0e1xiZXRhXzJ9JDogb25lLWxpbmVyIHRvIGRlZmluZSAkXGhhdHtcYmV0YV8yfSQKCgpgYGB7ciBjb21wMiwgIGVjaG89cHJpbnRfY29kZSwgZXZhbD1UUlVFfQojIC0gaW5wdXRzOiBmYWN0b3JzIG9mIHEKIyAtIG91dHB1dHM6IHEgdmFsdWUKY2h1bmtfcSA8LSBmdW5jdGlvbigpewojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMgIAoKICAgIHFfZnVuY3Rpb25fZiA8LSBmdW5jdGlvbihxX2lucHV0MV92YXIgPSBxX2lucHV0MV9zbyAsIHFfaW5wdXQyX3ZhciA9IHFfaW5wdXQyX3NvKSB7ICAKICAgICAgICAocV9pbnB1dDFfdmFyICogcV9pbnB1dDJfdmFyKV4yCgogICAgfQoKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjICAKICAgIHJldHVybihsaXN0KCJxX2Z1bmN0aW9uX2YiID0gcV9mdW5jdGlvbl9mKSkKfQoKaW52aXNpYmxlKCBsaXN0MmVudihjaHVua19xKCksLkdsb2JhbEVudikgKQoKYGBgCjwvZGV0YWlscz4KCiMjIEFwcHJvYWNoIDI6IFtIYW1vcnkgZXQgYWwuXShodHRwczovL2JpdHNzLW9wYS5naXRodWIuaW8vb3BhLWRld29ybWluZy8jcmVmLWtscHM0KQojIyMgQ29tcG9uZW50IDMgKCIkayQiKQoKVGhpcyBpcyB0aGUgZm9ybXVsYSB1c2VkIHRvIGNhbGN1bGF0ZSBjb21wb25lbnQgM1teM10KCjxkZXRhaWxzPjxzdW1tYXJ5PlNob3cgYWxsIHRoZSBkZXRhaWxzPC9zdW1tYXJ5PgpcYmVnaW57ZXF1YXRpb259CmsgPSBSIFx0aW1lcyBYICArICgxIC0gUikgXHRpbWVzIFgKXGxhYmVse2VxOjV9Clx0YWd7NX0KXGVuZHtlcXVhdGlvbn0KCldoZXJlOgoKLSAkayQ6IG9uZS1saW5lciB0byBkZWZpbmUgawotICRSJDogb25lLWxpbmVyIHRvIGRlZmluZSBSCgoKYGBge3IgY29tcDMsICBlY2hvPXByaW50X2NvZGUsIGV2YWw9VFJVRX0KIyAtIGlucHV0czogZmFjdG9ycyBvZiBxCiMgLSBvdXRwdXRzOiBxIHZhbHVlCmNodW5rX2sgPC0gZnVuY3Rpb24oKXsKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjICAKCiAgICBrX2Z1bmN0aW9uX2YgPC0gZnVuY3Rpb24oa19pbnB1dDFfdmFyID0ga19pbnB1dDFfc28gLCBrX2lucHV0Ml92YXIgPSBrX2lucHV0Ml9zbykgeyAgCiAgICAgICAgKGtfaW5wdXQxX3ZhciAqIGtfaW5wdXQyX3ZhcileMgoKICAgIH0KCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyAgCiAgICByZXR1cm4obGlzdCgia19mdW5jdGlvbl9mIiA9IGtfZnVuY3Rpb25fZikpCn0KCmludmlzaWJsZSggbGlzdDJlbnYoY2h1bmtfaygpLC5HbG9iYWxFbnYpICkKCgpgYGAKCjwvZGV0YWlscz4KIyMgU3VtbWFyeSBvZiBBbGwgQXBwcm9hY2hlcwoKCnwgQXBwcm9hY2ggICAgfCBQYXJ0IDEgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgUGFydCAyICAgICAgICB8CnwtLS0tLS0tLS18LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLXwKfCAxLjEgfCBTcGVjaWZpY2F0aW9uIG9mIEFwcHJvYWNoIDEgd2l0aCBQYXJ0IDEgQXNzdW1wdGlvbiAxIHwgU3BlY2lmaWNhdGlvbiBvZiBBcHByb2FjaCAxIHdpdGggUGFydCAyIEFzc3VtcHRpb24gMSAgfAp8IDEuMiB8IFNwZWNpZmljYXRpb24gb2YgQXBwcm9hY2ggMSB3aXRoIFBhcnQgMSBBc3N1bXB0aW9uIDIgfCBTcGVjaWZpY2F0aW9uIG9mIEFwcnJvYWNoIDEgd2l0aCBQYXJ0IDIgQXNzdW1wdGlvbiAyICB8CnwgMi4xIHwgU3BlY2lmaWNhdGlvbiBvZiBBcHByb2FjaCAyIHdpdGggUGFydCAxIEFzc3VtcHRpb24gMSB8IFNwZWNpZmljYXRpb24gb2YgQXBwcm9hY2ggMiB3aXRoIFBhcnQgMiBBc3N1bXB0aW9uIDEgfAp8ICoqMi4yKiogfCAqKlNwZWNpZmljYXRpb24gb2YgQXBwcm9hY2ggMiB3aXRoIFBhcnQgMSBBc3N1bXB0aW9uIDIqKiB8ICoqU3BlY2lmaWNhdGlvbiBvZiBBcHByb2FjaCAyIHdpdGggUGFydCAyIEFzc3VtcHRpb24gMioqfAoKQm9sZGVkIHJvdyBpcyB0aGUgYXNzdW1wdGlvbnMgYW5kIHRoZSBhcHByb2FjaCB3ZSB1c2UgdG8gZ2VuZXJhdGUgdGhlIG1haW4gcG9saWN5IGVzdGltYXRlIHBsb3QuCgoKIyBNYWluIHJlc3VsdHMKPGRldGFpbHM+PHN1bW1hcnk+U2hvdyBhbGwgdGhlIGRldGFpbHM8L3N1bW1hcnk+CmBgYHtyIGFsbC1zdGVwcywgIGVjaG89cHJpbnRfY29kZSwgZXZhbCA9IFRSVUV9CiN1bml0IHRlc3QgZnVuY3Rpb24KdW5pdF90ZXN0X2YgPC0gZnVuY3Rpb24odG9fdGVzdF92YXIsIG9yaWdpbmFsX3ZhciwgbWFpbl9ydW5fdmFyID0gVFJVRSl7CiAgICBpZiAobWFpbl9ydW5fdmFyID09IFRSVUUpIHsKICAgICAgICBpZiAobGVuZ3RoKHRvX3Rlc3RfdmFyKSA+IDEpIHsKICAgICAgICAgICAgZmFpbHNfdGVzdCA8LSAoIGFicyhzZCh0b190ZXN0X3ZhcikgLSBvcmlnaW5hbF92YXIpID4gMC4wMDAxICkKICAgICAgICAgICAgdGV4dF92YWwgPC0gc2QodG9fdGVzdF92YXIpCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZmFpbHNfdGVzdCA8LSAoIGFicyh0b190ZXN0X3ZhciAtIG9yaWdpbmFsX3ZhcikgPiAwLjAwMDEgKQogICAgICAgICAgICB0ZXh0X3ZhbCA8LSB0b190ZXN0X3ZhcgogICAgICAgIH0KICAgICAgICBpZiAoZmFpbHNfdGVzdCkgewogICAgICAgICAgICBwcmludChwYXN0ZSgiT3V0cHV0IGhhcyBjaGFuZ2UgYXQiLAogICAgICAgICAgICAgICAgICAgICAgICBkZXBhcnNlKHN1YnN0aXR1dGUodG9fdGVzdF92YXIpICksCiAgICAgICAgICAgICAgICAgICAgICAgICIgdG8gIiwgdGV4dF92YWwpICkKICAgICAgICB9CiAgICAgIH0KfQoKb25lX3J1biA8LQogIGZ1bmN0aW9uKHJfaW5wdXQxX3ZhcjEgPSByX2lucHV0MV9zbywKICAgICAgICAgICByX2lucHV0Ml92YXIxID0gcl9pbnB1dDJfc28sCiAgICAgICAgICAgcV9pbnB1dDFfdmFyMSA9IHFfaW5wdXQxX3NvLAogICAgICAgICAgIHFfaW5wdXQyX3ZhcjEgPSBxX2lucHV0Ml9zbywKICAgICAgICAgICBrX2lucHV0MV92YXIxID0ga19pbnB1dDFfc28sCiAgICAgICAgICAga19pbnB1dDJfdmFyMSA9IGtfaW5wdXQyX3NvKXsjIFZhcmlhYmxlcyBuZWVkZWQgdG8gZ2VuZXJhdGUgdGhlIGZpbmFsIHBvbGljeSBlc3RpbWF0ZXMKCiAgICByX2luIDwtIHJfZnVuY3Rpb25fZihyX2lucHV0MV92YXIgPSByX2lucHV0MV92YXIxLAogICAgICAgICAgICAgICAgICAgICAgICAgcl9pbnB1dDJfdmFyID0gcl9pbnB1dDJfdmFyMSkKICAgIHFfaW4gPC0gcV9mdW5jdGlvbl9mKHFfaW5wdXQxX3ZhciA9IHFfaW5wdXQxX3ZhcjEsCiAgICAgICAgICAgICAgICAgICAgICAgICBxX2lucHV0Ml92YXIgPSBxX2lucHV0Ml92YXIxKQogICAga19pbiA8LSBrX2Z1bmN0aW9uX2Yoa19pbnB1dDFfdmFyID0ga19pbnB1dDFfdmFyMSwKICAgICAgICAgICAgICAgICAgICAgICAgIGtfaW5wdXQyX3ZhciA9IGtfaW5wdXQyX3ZhcjEpCiAgICByZXR1cm4gKGxpc3QoInJfaW4iID0gcl9pbiwKICAgICAgICAgICAgICAgICAicV9pbiIgPSBxX2luLAogICAgICAgICAgICAgICAgICJrX2luIiA9IGtfaW4pKQogICAgICAgICAgIH0KCmludmlzaWJsZShsaXN0MmVudihvbmVfcnVuKCksIC5HbG9iYWxFbnYpKQoKCmBgYAoKPC9kZXRhaWxzPgpgYGB7ciBtYWluLXJlc3VsdHMsICBlY2hvPXByaW50X2NvZGUsIGV2YWwgPSBUUlVFfQojIC0gcGVyZm9ybSB0aGUgY2FsY3VsYXRpb25zIHRvIGFjaGlldmUgZmluYWwgcmVzdWx0cwoKcmVzdWx0MSA8LSBtYWluZXF1YXRpb25fZihyX2ZpbmFsX3ZhciA9IHJfaW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgcV9maW5hbF92YXIgPSBxX2luLAogICAgICAgICAgICAgICAgICAgICAgICAgIGtfZmluYWxfdmFyID0ga19pbikKcmVzdWx0MiA8LSBhbHRlcm5hdGl2ZV9mKHJfZmluYWxfdmFyID0gcl9pbiwKICAgICAgICAgICAgICAgICAgICAgICAgICBxX2ZpbmFsX3ZhciA9IHFfaW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAga19maW5hbF92YXIgPSBrX2luKQojLi4uCgpyZXN1bHRzX3RhYmxlIDwtIGRhdGEuZnJhbWUoInJlc3VsdHMxIiA9ICAgYygicmVzdWx0cyIsIE5BLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOQSkgLAogICAgICAgICAgICAgICAgICAgICAgICAicmVzdWx0czIiID0gIGMoTkEsICJyZXN1bHRzIiwgTkEpLAogICAgICAgICAgICAgICAgICAgICAgICAicmVzdWx0czMiID0gYygicmVzdWx0cyIsIE5BLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAicmVzdWx0cyIpLAoKICAgICAgICAgICAgICAgICAgICAgICAgcm93Lm5hbWVzID0gYygic2l0dWF0aW9uMSIsICJzaXR1YXRpb24yIiwgInNpdHVhdGlvbjMiKSkKCmthYmxlKHJlc3VsdHNfdGFibGUsIGNhcHRpb24gPSAiVGFibGUgQ2FwdGlvbiIpICU+JQogIGthYmxlX3N0eWxpbmcoInN0cmlwZWQiLCBmdWxsX3dpZHRoID0gRikKYGBgCgoKYGBge3IgZ2VuZXJhdGUtcGxvdC1mdW5jdGlvbiwgcHVybCA9IFRSVUUsIGVjaG8gPSBGQUxTRX0KIyBnZW5lcmF0ZV9wbG90X2Y6IGZ1bmN0aW9uIHRvIGdlbmVyYXRlIHBsb3RzIGZvciBib3RoIER5bmFtaWMgRG9jdW1lbnQgYW5kCiMgc2hpbnkgYXBwLiBJdCB0YWtlcyBpbiB0aGUgc2ltdWxhdGVkIGRhdGEsIHBvbGljeSBlc3RpbWF0ZSB0ZXh0LCBhbmQgcmVzY2FsZQojIHZhcmlhYmxlLiBUaGVzZSBhcmUgaW50ZXJtZWRpYXJ5IHZhcmlhYmxlcyB0byBleGNsdWRlIHRoZSBpbnRlcmFjdGl2aXR5IG9mCiMgc2hpbnkgYXBwIGZyb20gdGhlIHBsb3QgZ2VuZXJhdGlvbiBwcm9jZXNzLiAgCmNodW5rX2dlbmVyYXRlX3Bsb3QgPC0gZnVuY3Rpb24oKSB7CiAgZ2VuZXJhdGVfcGxvdF9mIDwtIGZ1bmN0aW9uKHJlc3VsdDFfc2ltX2FsbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9saWN5X2VzdGltYXRlc190ZXh0X3NlbGVjdGVkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNjYWxlLCBTRCA9IEZBTFNFKXsKICAgIHRvdGFsX3RpbWVfc2ltIDwtIHJlc3VsdDFfc2ltX2FsbCR0b3RhbF90aW1lX3NpbQogICAgcG9zaXRpb24gPC0gd2hpY2goIHBvbGljeV9lc3RpbWF0ZXNfdGV4dCA9PSBwb2xpY3lfZXN0aW1hdGVzX3RleHRfc2VsZWN0ZWQpCiAgICByZXN1bHQxX3NpbSA8LSByZXN1bHQxX3NpbV9hbGxbWyBwb2xpY3lfZXN0aW1hdGVzX3Zhcm5hbWVzW3Bvc2l0aW9uXSBdXSAgICAKICAgIHJlc3VsdDFfZm9yX3RleHQgPC0gcGFzdGUoIk1lZGlhbiBOUFY6ICIsIHJvdW5kKG1lZGlhbihyZXN1bHQxX3NpbSksIDIpKQogICAgcmVzdWx0MV9mb3JfdGV4dDIgPC0gTlVMTAogICAgaWYgKFNEKXsKICAgIHJlc3VsdDFfZm9yX3RleHQyIDwtIHBhc3RlKCJTRCBOUFY6ICIsIHJvdW5kKHNkKHJlc3VsdDFfc2ltKSwgMikpCiAgICB9CiAgICBwbG90MSA8LSBnZ3Bsb3QoKSArCiAgICAgIGdlb21fZGVuc2l0eSgKICAgICAgICBhZXMoeCA9IHJlc3VsdDFfc2ltLAogICAgICAgICAgICBhbHBoYSA9IDEgLyAyLCAuLnNjYWxlZC4uKSwKICAgICAgICBrZXJuZWwgPSAiZ2F1IiwKICAgICAgICBsd2QgPSAxLAogICAgICAgIGZpbGwgPSAiIzAwN2JhNyIsCiAgICAgICAgY29sb3IgPSAiZGFya2JsdWUiLAogICAgICAgIGFscGhhID0gMC4zCiAgICAgICkgKwogICAgICBnZW9tX3ZsaW5lKAogICAgICAgIHhpbnRlcmNlcHQgPSBjKDAsIG1lZGlhbihyZXN1bHQxX3NpbSkpLAogICAgICAgIGNvbCA9IGMoImJsYWNrIiwgImRhcmtibHVlIiksCiAgICAgICAgbHdkID0gYygxLCAxKSwKICAgICAgICBsaW5ldHlwZSA9IGMoInNvbGlkIiwgImRhc2hlZCIpCiAgICAgICkgKwogICAgICBjb29yZF9jYXJ0ZXNpYW4oeGxpbSA9IGMoLTMwMCwxMDAwKSwgIHlsaW0gPSAgYyggMCwgMS4yICkpICArICAjIGZpeGluZyB0aGUgeCBheGlzIHNvIHNoaWZ0cyBpbiB0aGUgZGVuc2l0eSBjYW4gYmUgc2VlbgogICAgICAjeGxpbShyYW5nZShkZW5zaXR5KHJlc3VsdDFfc2ltKSR4KSkgKwogICAgICBndWlkZXMoYWxwaGEgPSAibm9uZSIsIGNvbG91ciA9ICJub25lIikgKwogICAgICBzY2FsZV94X2NvbnRpbnVvdXMoZXhwYW5kID0gZXhwYW5zaW9uKG11bHQgPSBjKDAsIDApKSkgKwogICAgICBzY2FsZV95X2NvbnRpbnVvdXMoZXhwYW5kID0gZXhwYW5zaW9uKG11bHQgPSBjKDAsIDApKSkgKwogICAgICBhbm5vdGF0ZSgKICAgICAgICAidGV4dCIsCiAgICAgICAgeCA9IDEgKiBtZWRpYW4ocmVzdWx0MV9zaW0pLAogICAgICAgIHkgPSAwLjIsCiAgICAgICAgbGFiZWwgPSByZXN1bHQxX2Zvcl90ZXh0LAogICAgICAgIHNpemUgPSA2LAogICAgICAgIGNvbG9yID0gImRhcmtibHVlIgogICAgICApICsKICAgICAgYW5ub3RhdGUoCiAgICAgICAgInRleHQiLAogICAgICAgIHggPSAxICogbWVkaWFuKHJlc3VsdDFfc2ltKSwKICAgICAgICB5ID0gMC4xLAogICAgICAgIGxhYmVsID0gcmVzdWx0MV9mb3JfdGV4dDIsCiAgICAgICAgc2l6ZSA9IDYsCiAgICAgICAgY29sb3IgPSAiZGFya2JsdWUiCiAgICAgICkgKwogICAgICB0aGVtZSgKICAgICAgICBheGlzLnRpY2tzID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxOCksCiAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxOCksCiAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMjQpLAogICAgICAgIHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSwKICAgICAgICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMubGluZS54ID0gZWxlbWVudF9saW5lKGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDEuNSkKICAgICAgKQoKICAgIGlmIChyZXNjYWxlID09IFRSVUUpIHsKICAgICAgcGxvdDEgPC0KICAgICAgICBzdXBwcmVzc01lc3NhZ2VzKHBsb3QxICsgY29vcmRfY2FydGVzaWFuKHhsaW0gPSAxLjIgKiBjKG1pbihjKAogICAgICAgICAgLTEsIHJlc3VsdDFfc2ltCiAgICAgICAgKSksIG1heChjKAogICAgICAgICAgMTAwLCByZXN1bHQxX3NpbQogICAgICAgICkpKSkpCiAgICB9CiAgICByZXR1cm4gKGxpc3QocGxvdDEscG9zaXRpb24sdG90YWxfdGltZV9zaW0pKQp9CiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCnJldHVybihsaXN0KCJnZW5lcmF0ZV9wbG90X2YiID0gZ2VuZXJhdGVfcGxvdF9mKSkKfQoKaW52aXNpYmxlKCBsaXN0MmVudihjaHVua19nZW5lcmF0ZV9wbG90KCksLkdsb2JhbEVudikgKQpgYGAKCiMgTW9udGUgQ2FybG8gU2ltdWxhdGlvbnMgIApgYGB7ciBtYy1zZXR1cCwgIGVjaG89cHJpbnRfY29kZSwgZXZhbCA9IFRSVUV9CgpzaW1fZGF0YTFfZiA8LSBmdW5jdGlvbihuc2ltcyA9IDFlMiwKICAgICAgICAgICAgICAgICAgICAgIHJfaW5wdXQxX3ZhcjIsCiAgICAgICAgICAgICAgICAgICAgICByX2lucHV0MV92YXIyX3NkLAogICAgICAgICAgICAgICAgICAgICAgcl9pbnB1dDJfdmFyMiwKICAgICAgICAgICAgICAgICAgICAgIHJfaW5wdXQyX3ZhcjJfc2QsCiAgICAgICAgICAgICAgICAgICAgICBxX2lucHV0MV92YXIyLAogICAgICAgICAgICAgICAgICAgICAgcV9pbnB1dDFfdmFyMl9zZCwKICAgICAgICAgICAgICAgICAgICAgIHFfaW5wdXQyX3ZhcjIsCiAgICAgICAgICAgICAgICAgICAgICBxX2lucHV0Ml92YXIyX3NkLAogICAgICAgICAgICAgICAgICAgICAga19pbnB1dDFfdmFyMiwKICAgICAgICAgICAgICAgICAgICAgIGtfaW5wdXQxX3ZhcjJfc2QsCiAgICAgICAgICAgICAgICAgICAgICBrX2lucHV0Ml92YXIyLAogICAgICAgICAgICAgICAgICAgICAga19pbnB1dDJfdmFyMl9zZCl7CiAgICAjIyMjIyMjIyMjIyMjIyMjCiAgICAjIyMjIyMgRHJhd3MgICAKICAgICMjIyMjIyMjIyMjIyMjIyMgIAogIHN0YXJ0X3RpbWUgPC0gU3lzLnRpbWUoKQogIHNldC5zZWVkKDE0Mjg1NykKICByMV9zaW0gPC0gcm5vcm0obiA9IG5zaW1zLCBtZWFuID0gcl9pbnB1dDFfdmFyMiwgc2Q9IHJfaW5wdXQxX3ZhcjJfc2QpCiAgcjJfc2ltIDwtIHJub3JtKG4gPSBuc2ltcywgbWVhbiA9IHJfaW5wdXQyX3ZhcjIsIHNkPSByX2lucHV0Ml92YXIyX3NkKQogIHExX3NpbSA8LSBybm9ybShuID0gbnNpbXMsIG1lYW4gPSBxX2lucHV0MV92YXIyLCBzZD0gcV9pbnB1dDFfdmFyMl9zZCkKICBxMl9zaW0gPC0gcm5vcm0obiA9IG5zaW1zLCBtZWFuID0gcV9pbnB1dDJfdmFyMiwgc2Q9IHFfaW5wdXQyX3ZhcjJfc2QpCiAgazFfc2ltIDwtIHJub3JtKG4gPSBuc2ltcywgbWVhbiA9IGtfaW5wdXQxX3ZhcjIsIHNkPSBrX2lucHV0MV92YXIyX3NkKQogIGsyX3NpbSA8LSBybm9ybShuID0gbnNpbXMsIG1lYW4gPSBrX2lucHV0Ml92YXIyLCBzZD0ga19pbnB1dDJfdmFyMl9zZCkKCgoKCgogICAgIyMjIyMjIyMjIyMjIyMjIwogICAgIyMjIyMjIFJ1bnMgICAgCiAgICAjIyMjIyMjIyMjIyMjIyMjCgogIHJlc3VsdDFfc2ltIDwtIHJlcChOQSwgbnNpbXMpICNyZXN1bHQxCiAgcmVzdWx0Ml9zaW0gPC0gcmVwKE5BLCBuc2ltcykgI3Jlc3VsdDIKCiAgZm9yIChpIGluIDE6bnNpbXMpewogICAgaW52aXNpYmxlKGxpc3QyZW52KAogICAgICBvbmVfcnVuKHJfaW5wdXQxX3ZhcjEgPSByMV9zaW1baV0sCiAgICAgICAgICAgICAgcl9pbnB1dDJfdmFyMSA9IHIyX3NpbVtpXSwKICAgICAgICAgICAgICBxX2lucHV0MV92YXIxID0gcTFfc2ltW2ldLAogICAgICAgICAgICAgIHFfaW5wdXQyX3ZhcjEgPSBxMl9zaW1baV0sCiAgICAgICAgICAgICAga19pbnB1dDFfdmFyMSA9IGsxX3NpbVtpXSwKICAgICAgICAgICAgICBrX2lucHV0Ml92YXIxID0gazJfc2ltW2ldCiAgICAgICAgICAgICAgKSwgLkdsb2JhbEVudikpCgogICAgcmVzdWx0MV9zaW1baV0gPC0gbWFpbmVxdWF0aW9uX2Yocl9maW5hbF92YXIgPSByX2luLAogICAgICAgICAgICAgICAgICAgICAgICAgIHFfZmluYWxfdmFyID0gcV9pbiwKICAgICAgICAgICAgICAgICAgICAgICAgICBrX2ZpbmFsX3ZhciA9IGtfaW4pCiAgICByZXN1bHQyX3NpbVtpXSA8LSBhbHRlcm5hdGl2ZV9mKHJfZmluYWxfdmFyID0gcl9pbiwKICAgICAgICAgICAgICAgICAgICAgICAgICBxX2ZpbmFsX3ZhciA9IHFfaW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAga19maW5hbF92YXIgPSBrX2luKQogIH0KICAgIHRvdGFsX3RpbWUgPC0gU3lzLnRpbWUoKSAtIHN0YXJ0X3RpbWUKICAgIHJldHVybihsaXN0KCJyZXN1bHQxX3NpbSIgPSByZXN1bHQxX3NpbSwKICAgICAgICAgICAgICAgICJyZXN1bHQyX3NpbSIgPSByZXN1bHQyX3NpbSkpCgoKfQoKcG9saWN5X2VzdGltYXRlc192YXJuYW1lcyA8LSBjKAogICJyZXN1bHQxX3NpbSIsCiAgInJlc3VsdDJfc2ltIgopCgpwb2xpY3lfZXN0aW1hdGVzX3RleHQgPC0gYygKICAiTWFpbiBFcXVhdGlvbiIsCiAgIkFsdGVybmF0aXZlIEVxdWF0aW9uIgopCgpgYGAKCmBgYHtyIG1jLXJ1biwgZHBpID0gNDAwLCBlY2hvID0gcHJpbnRfY29kZSwgZXZhbCA9IFRSVUV9CiMgUnVuIE1vbnRlIENhcmxvIHNpbXVsYXRpb24gZm9yIG91ciBtYWluIG1vZGVsCnJlc3VsdDFfc2ltX2FsbCA8LSBzaW1fZGF0YTFfZihuc2ltcyA9IG5zaW1zX3NvLAogICAgICAgICAgICAgICAgICAgICAgcl9pbnB1dDFfdmFyMiA9IHJfaW5wdXQxX3NvLAogICAgICAgICAgICAgICAgICAgICAgcl9pbnB1dDFfdmFyMl9zZCA9IHJfaW5wdXQxX3NvICogMC4xLAogICAgICAgICAgICAgICAgICAgICAgcl9pbnB1dDJfdmFyMiA9IHJfaW5wdXQyX3NvLAogICAgICAgICAgICAgICAgICAgICAgcl9pbnB1dDJfdmFyMl9zZCA9IHJfaW5wdXQyX3NvICogMC4xLAogICAgICAgICAgICAgICAgICAgICAgcV9pbnB1dDFfdmFyMiA9IHFfaW5wdXQxX3NvLAogICAgICAgICAgICAgICAgICAgICAgcV9pbnB1dDFfdmFyMl9zZCA9IHFfaW5wdXQxX3NvICogMC4xLAogICAgICAgICAgICAgICAgICAgICAgcV9pbnB1dDJfdmFyMiA9IHFfaW5wdXQyX3NvLAogICAgICAgICAgICAgICAgICAgICAgcV9pbnB1dDJfdmFyMl9zZCA9IHFfaW5wdXQyX3NvICogMC4xLAogICAgICAgICAgICAgICAgICAgICAga19pbnB1dDFfdmFyMiA9IGtfaW5wdXQxX3NvLAogICAgICAgICAgICAgICAgICAgICAga19pbnB1dDFfdmFyMl9zZCA9IGtfaW5wdXQxX3NvICogMC4xLAogICAgICAgICAgICAgICAgICAgICAga19pbnB1dDJfdmFyMiA9IGtfaW5wdXQyX3NvLAogICAgICAgICAgICAgICAgICAgICAga19pbnB1dDJfdmFyMl9zZCA9IGtfaW5wdXQyX3NvICogMC4xCgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICkKCgoKIyMjIyMjIyMjIyMjIyMjIwojIyMjIyMgUmVzdWx0cy9WaXoKIyMjIyMjIyMjIyMjIyMjIwoKCmxpYnJhcnkocGxvdGx5KQoKCnBsb3QxIDwtIGdlbmVyYXRlX3Bsb3RfZihyZXN1bHQxX3NpbV9hbGwsIHBvbGljeV9lc3RpbWF0ZV9zbywgcmVzY2FsZV9zbylbWzFdXSArCiAgICAgIGxhYnMoeSA9IE5VTEwsCiAgICAgICB4ID0gIk1haW4gRXN0aW1hdGUiICwKICAgICAgIHRpdGxlID0gIlByb2plY3QgVGl0bGUiLAogICAgICAgc3VidGl0bGUgPSAiRGlzdHJpYnV0aW9uIG9mIEtleSBJbmRpY2F0b3IiCiAgICAgICApCnByaW50KHBsb3QxKQpgYGAKCgoKCiMgUmVmZXJlbmNlcwoKClteMV06IE5vdGVzIG9mIHJlZmVyZW5jZWQgc2VjdGlvbgoKClteMl06IE5vdGVzIG9uIHJlZmVyZW5jZWQgc2VjdGlvbgoKW14zXTogTm90ZXMgb24gcmVmZXJlbmNlZCBzZWN0aW9uCg==

An Open Policy Analysis by BITSS
See a full contributors list here
openpolicy@berkeley.edu